sitara_depot/components/free_rtos/ethernet_ip/eth_udp_client.cpp

149 lines
4.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* eth_udp_client.cpp
*
* Created on: 15 <20><><EFBFBD>. 2023 <20>.
* Author: sychev
*/
#include "free_rtos/ethernet_ip/eth_udp_client.hpp"
#include "free_rtos/base/swap.h"
#include "free_rtos/ethernet_ip/eth_udp_types.h"
#include "free_rtos/ethernet_ip/eth_ip_types.h"
#include "free_rtos/ethernet_ip/eth_checksum.h"
#include "free_rtos/ethernet_ip/eth_ip_prots_id.h"
#include <algorithm>
#include <cstring>
free_rtos::EthUpdClient::EthUpdClient(EthIpIface& ip_iface, TEthMacPorts port_id,
uint16_t port_dst_be, uint16_t port_src_be,
bool use_chksum) :
port_dst_be_{port_dst_be},
port_src_be_{port_src_be},
use_checksum_{use_chksum},
ip_iface_{ip_iface},
port_id_{port_id}
{
}
void free_rtos::EthUpdClient::put_data(uint32_t src_ip, uint8_t * p_data, uint32_t len)
{
if ((p_data == nullptr) || (len == 0)) {
return;
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD>
{
LockGuard lock(rx_mut_); /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (buff_.size() < max_buf_size) {
buff_.insert(buff_.end(), p_data, p_data + len);
}
}
src_ip_ = src_ip;
rx_sem_.post();
}
int32_t free_rtos::EthUpdClient::get_data(uint8_t * p_data, uint32_t len)
{
uint32_t size = buff_.size();
if (size > len) {
size = len;
}
{
LockGuard lock(rx_mut_); /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
auto item_begin = buff_.begin();
auto item_end = item_begin + size;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::copy(item_begin, item_end, p_data);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
buff_.erase(item_begin, item_end);
}
return size;
}
int32_t free_rtos::EthUpdClient::read(uint8_t * p_data, uint32_t len)
{
if ((p_data == nullptr) || (len == 0)) {
return 0;
}
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
while (buff_.empty()) { // Не заменять на if ! Иначе следующий прием получит пустой буфер т.к. семафор может быть не сброшен !
rx_sem_.pend();
}
return get_data(p_data, len);
}
int32_t free_rtos::EthUpdClient::read_async(uint8_t * p_data, uint32_t len)
{
if ((p_data == nullptr) || (len == 0)) {
return 0;
}
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (buff_.empty()) {
return 0;
}
return get_data(p_data, len);
}
void free_rtos::EthUpdClient::clear()
{
LockGuard lock(rx_mut_);
buff_.clear();
}
int32_t free_rtos::EthUpdClient::write(uint32_t ip_dst_be, uint8_t * p_data, uint32_t len)
{
TUdpHeader * hdr = (TUdpHeader *)(eth_pkt_.data + sizeof(TIpHeader) + sizeof(TEthFrameHeader));
uint8_t * p_udp_data = (uint8_t *)(eth_pkt_.data + sizeof(TIpHeader) + sizeof(TEthFrameHeader) + sizeof(TUdpHeader));
if (ip_dst_be == 0) {
ip_dst_be = src_ip_;
}
eth_pkt_.length = len + sizeof(TUdpHeader);
hdr->Src_port = port_src_be_;
hdr->Dst_port = port_dst_be_;
hdr->Length = BASE_SWAP16(eth_pkt_.length);
hdr->Chk_sum = 0;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memcpy(p_udp_data, p_data, len);
/// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>
if (use_checksum_) {
uint32_t self_ip = ip_iface_.getSelfIpAddr();
uint32_t chk_sum32 = 0;
uint8_t * const dst_ip = (uint8_t *)&ip_dst_be;
uint8_t * const src_ip = (uint8_t *)&self_ip;
for (int j = 0; j < ETH_IP_ADDR_LEN; j += 2)
{
chk_sum32 += ((uint16_t)dst_ip[j] << 8) + dst_ip[j+1];
chk_sum32 += ((uint16_t)src_ip[j] << 8) + src_ip[j+1];
}
chk_sum32 += IP_PROT_UDP + eth_pkt_.length;
uint16_t chk_sum16 = eth_calcChksum(chk_sum32, (uint8_t *)hdr, eth_pkt_.length);
hdr->Chk_sum = BASE_SWAP16(chk_sum16);
}
return ip_iface_.send(port_id_, ip_dst_be, IP_PROT_UDP, eth_pkt_);
}