14static const char *
const TAG =
"api.frame_helper";
16#define HELPER_LOG(msg, ...) \
17 ESP_LOGVV(TAG, "%s (%s): " msg, this->client_info_->name.c_str(), this->client_info_->peername.c_str(), ##__VA_ARGS__)
19#ifdef HELPER_LOG_PACKETS
20#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
21#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str())
23#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
24#define LOG_PACKET_SENDING(data, len) ((void) 0)
32 return LOG_STR(
"WOULD_BLOCK");
34 return LOG_STR(
"BAD_INDICATOR");
36 return LOG_STR(
"BAD_DATA_PACKET");
38 return LOG_STR(
"TCP_NODELAY_FAILED");
40 return LOG_STR(
"TCP_NONBLOCKING_FAILED");
42 return LOG_STR(
"CLOSE_FAILED");
44 return LOG_STR(
"SHUTDOWN_FAILED");
46 return LOG_STR(
"BAD_STATE");
48 return LOG_STR(
"BAD_ARG");
50 return LOG_STR(
"SOCKET_READ_FAILED");
52 return LOG_STR(
"SOCKET_WRITE_FAILED");
54 return LOG_STR(
"OUT_OF_MEMORY");
56 return LOG_STR(
"CONNECTION_CLOSED");
60 return LOG_STR(
"BAD_HANDSHAKE_PACKET_LEN");
62 return LOG_STR(
"HANDSHAKESTATE_READ_FAILED");
64 return LOG_STR(
"HANDSHAKESTATE_WRITE_FAILED");
66 return LOG_STR(
"HANDSHAKESTATE_BAD_STATE");
68 return LOG_STR(
"CIPHERSTATE_DECRYPT_FAILED");
70 return LOG_STR(
"CIPHERSTATE_ENCRYPT_FAILED");
72 return LOG_STR(
"HANDSHAKESTATE_SETUP_FAILED");
74 return LOG_STR(
"HANDSHAKESTATE_SPLIT_FAILED");
76 return LOG_STR(
"BAD_HANDSHAKE_ERROR_BYTE");
79 return LOG_STR(
"UNKNOWN");
95 if (errno == EWOULDBLOCK || errno == EAGAIN) {
98 HELPER_LOG(
"Socket write failed with errno %d", errno);
108 HELPER_LOG(
"Send queue full (%u buffers), dropping connection", this->
tx_buf_count_);
113 uint16_t buffer_size = total_write_len - offset;
115 buffer = std::make_unique<SendBuffer>(
SendBuffer{
116 .data = std::make_unique<uint8_t[]>(buffer_size),
121 uint16_t to_skip = offset;
122 uint16_t write_pos = 0;
124 for (
int i = 0; i < iovcnt; i++) {
125 if (to_skip >= iov[i].iov_len) {
127 to_skip -=
static_cast<uint16_t
>(iov[i].
iov_len);
130 const uint8_t *src =
reinterpret_cast<uint8_t *
>(iov[i].
iov_base) + to_skip;
131 uint16_t
len =
static_cast<uint16_t
>(iov[i].
iov_len) - to_skip;
132 std::memcpy(buffer->data.get() + write_pos, src,
len);
151#ifdef HELPER_LOG_PACKETS
152 for (
int i = 0; i < iovcnt; i++) {
153 LOG_PACKET_SENDING(
reinterpret_cast<uint8_t *
>(iov[i].iov_base), iov[i].iov_len);
186 }
else if (
static_cast<uint16_t
>(sent) < total_write_len) {
207 }
else if (sent == 0) {
210 }
else if (
static_cast<uint16_t
>(sent) < front_buffer->
remaining()) {
213 front_buffer->
offset +=
static_cast<uint16_t
>(sent);
229 HELPER_LOG(
"Bad state for init %d", (
int)
state_);
235 HELPER_LOG(
"Setting nonblocking failed with errno %d", errno);
243 HELPER_LOG(
"Setting nodelay failed with errno %d", errno);
250 if (received == -1) {
251 if (errno == EWOULDBLOCK || errno == EAGAIN) {
255 HELPER_LOG(
"Socket read failed with errno %d", errno);
257 }
else if (received == 0) {
259 HELPER_LOG(
"Connection closed");
APIError handle_socket_read_result_(ssize_t received)
std::array< std::unique_ptr< SendBuffer >, API_MAX_SEND_QUEUE > tx_buf_
void buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len, uint16_t offset)
APIError handle_socket_write_error_()
APIError try_send_tx_buf_()
APIError write_raw_(const struct iovec *iov, int iovcnt, uint16_t total_write_len)
virtual ssize_t write(const void *buf, size_t len)=0
virtual int setblocking(bool blocking)=0
virtual ssize_t writev(const struct iovec *iov, int iovcnt)=0
virtual int setsockopt(int level, int optname, const void *optval, socklen_t optlen)=0
const LogString * api_error_to_logstr(APIError err)
@ HANDSHAKESTATE_READ_FAILED
@ HANDSHAKESTATE_BAD_STATE
@ HANDSHAKESTATE_SPLIT_FAILED
@ BAD_HANDSHAKE_PACKET_LEN
@ BAD_HANDSHAKE_ERROR_BYTE
@ HANDSHAKESTATE_SETUP_FAILED
@ CIPHERSTATE_ENCRYPT_FAILED
@ CIPHERSTATE_DECRYPT_FAILED
@ HANDSHAKESTATE_WRITE_FAILED
uint16_t remaining() const
const uint8_t * current_data() const