14static const char *
const TAG =
"api.frame_helper";
16#define HELPER_LOG(msg, ...) ESP_LOGVV(TAG, "%s: " msg, this->client_info_->get_combined_info().c_str(), ##__VA_ARGS__)
18#ifdef HELPER_LOG_PACKETS
19#define LOG_PACKET_RECEIVED(buffer) ESP_LOGVV(TAG, "Received frame: %s", format_hex_pretty(buffer).c_str())
20#define LOG_PACKET_SENDING(data, len) ESP_LOGVV(TAG, "Sending raw: %s", format_hex_pretty(data, len).c_str())
22#define LOG_PACKET_RECEIVED(buffer) ((void) 0)
23#define LOG_PACKET_SENDING(data, len) ((void) 0)
33 return "BAD_INDICATOR";
35 return "BAD_DATA_PACKET";
37 return "TCP_NODELAY_FAILED";
39 return "TCP_NONBLOCKING_FAILED";
41 return "CLOSE_FAILED";
43 return "SHUTDOWN_FAILED";
49 return "SOCKET_READ_FAILED";
51 return "SOCKET_WRITE_FAILED";
53 return "OUT_OF_MEMORY";
55 return "CONNECTION_CLOSED";
59 return "BAD_HANDSHAKE_PACKET_LEN";
61 return "HANDSHAKESTATE_READ_FAILED";
63 return "HANDSHAKESTATE_WRITE_FAILED";
65 return "HANDSHAKESTATE_BAD_STATE";
67 return "CIPHERSTATE_DECRYPT_FAILED";
69 return "CIPHERSTATE_ENCRYPT_FAILED";
71 return "HANDSHAKESTATE_SETUP_FAILED";
73 return "HANDSHAKESTATE_SPLIT_FAILED";
75 return "BAD_HANDSHAKE_ERROR_BYTE";
94 if (errno == EWOULDBLOCK || errno == EAGAIN) {
97 HELPER_LOG(
"Socket write failed with errno %d", errno);
106 buffer.
size = total_write_len - offset;
107 buffer.
data = std::make_unique<uint8_t[]>(buffer.
size);
109 uint16_t to_skip = offset;
110 uint16_t write_pos = 0;
112 for (
int i = 0; i < iovcnt; i++) {
113 if (to_skip >= iov[i].iov_len) {
115 to_skip -=
static_cast<uint16_t
>(iov[i].
iov_len);
118 const uint8_t *src =
reinterpret_cast<uint8_t *
>(iov[i].
iov_base) + to_skip;
119 uint16_t
len =
static_cast<uint16_t
>(iov[i].
iov_len) - to_skip;
120 std::memcpy(buffer.
data.get() + write_pos, src,
len);
125 this->
tx_buf_.push_back(std::move(buffer));
136#ifdef HELPER_LOG_PACKETS
137 for (
int i = 0; i < iovcnt; i++) {
138 LOG_PACKET_SENDING(
reinterpret_cast<uint8_t *
>(iov[i].iov_base), iov[i].iov_len);
171 }
else if (
static_cast<uint16_t
>(sent) < total_write_len) {
183 bool tx_buf_empty =
false;
184 while (!tx_buf_empty) {
193 }
else if (sent == 0) {
196 }
else if (
static_cast<uint16_t
>(sent) < front_buffer.
remaining()) {
199 front_buffer.
offset +=
static_cast<uint16_t
>(sent);
205 tx_buf_empty = this->
tx_buf_.empty();
215 HELPER_LOG(
"Bad state for init %d", (
int)
state_);
221 HELPER_LOG(
"Setting nonblocking failed with errno %d", errno);
229 HELPER_LOG(
"Setting nodelay failed with errno %d", errno);
236 if (received == -1) {
237 if (errno == EWOULDBLOCK || errno == EAGAIN) {
241 HELPER_LOG(
"Socket read failed with errno %d", errno);
243 }
else if (received == 0) {
245 HELPER_LOG(
"Connection closed");
APIError handle_socket_read_result_(ssize_t received)
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)
std::deque< SendBuffer > tx_buf_
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
@ 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
const char * api_error_to_str(APIError err)
uint16_t remaining() const
const uint8_t * current_data() const
std::unique_ptr< uint8_t[]> data