mirror of
https://github.com/esphome/esphome.git
synced 2025-10-31 23:21:54 +00:00
wip
This commit is contained in:
@@ -76,6 +76,16 @@ APIError APIFrameHelper::loop() {
|
|||||||
return APIError::OK; // Convert WOULD_BLOCK to OK to avoid connection termination
|
return APIError::OK; // Convert WOULD_BLOCK to OK to avoid connection termination
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Common socket write error handling
|
||||||
|
APIError APIFrameHelper::handle_socket_write_error_() {
|
||||||
|
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
||||||
|
return APIError::WOULD_BLOCK;
|
||||||
|
}
|
||||||
|
ESP_LOGVV(TAG, "%s: Socket write failed with errno %d", this->info_.c_str(), errno);
|
||||||
|
this->state_ = State::FAILED;
|
||||||
|
return APIError::SOCKET_WRITE_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper method to buffer data from IOVs
|
// Helper method to buffer data from IOVs
|
||||||
void APIFrameHelper::buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len) {
|
void APIFrameHelper::buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len) {
|
||||||
SendBuffer buffer;
|
SendBuffer buffer;
|
||||||
@@ -124,15 +134,13 @@ APIError APIFrameHelper::write_raw_(const struct iovec *iov, int iovcnt) {
|
|||||||
ssize_t sent = this->socket_->writev(iov, iovcnt);
|
ssize_t sent = this->socket_->writev(iov, iovcnt);
|
||||||
|
|
||||||
if (sent == -1) {
|
if (sent == -1) {
|
||||||
if (errno == EWOULDBLOCK || errno == EAGAIN) {
|
APIError err = this->handle_socket_write_error_();
|
||||||
|
if (err == APIError::WOULD_BLOCK) {
|
||||||
// Socket would block, buffer the data
|
// Socket would block, buffer the data
|
||||||
this->buffer_data_from_iov_(iov, iovcnt, total_write_len);
|
this->buffer_data_from_iov_(iov, iovcnt, total_write_len);
|
||||||
return APIError::OK; // Success, data buffered
|
return APIError::OK; // Success, data buffered
|
||||||
}
|
}
|
||||||
// Socket error
|
return err; // Socket write failed
|
||||||
ESP_LOGVV(TAG, "%s: Socket write failed with errno %d", this->info_.c_str(), errno);
|
|
||||||
this->state_ = State::FAILED;
|
|
||||||
return APIError::SOCKET_WRITE_FAILED; // Socket write failed
|
|
||||||
} else if (static_cast<uint16_t>(sent) < total_write_len) {
|
} else if (static_cast<uint16_t>(sent) < total_write_len) {
|
||||||
// Partially sent, buffer the remaining data
|
// Partially sent, buffer the remaining data
|
||||||
SendBuffer buffer;
|
SendBuffer buffer;
|
||||||
@@ -173,14 +181,7 @@ APIError APIFrameHelper::try_send_tx_buf_() {
|
|||||||
ssize_t sent = this->socket_->write(front_buffer.current_data(), front_buffer.remaining());
|
ssize_t sent = this->socket_->write(front_buffer.current_data(), front_buffer.remaining());
|
||||||
|
|
||||||
if (sent == -1) {
|
if (sent == -1) {
|
||||||
if (errno != EWOULDBLOCK && errno != EAGAIN) {
|
return this->handle_socket_write_error_();
|
||||||
// Real socket error (not just would block)
|
|
||||||
ESP_LOGVV(TAG, "%s: Socket write failed with errno %d", this->info_.c_str(), errno);
|
|
||||||
this->state_ = State::FAILED;
|
|
||||||
return APIError::SOCKET_WRITE_FAILED; // Socket write failed
|
|
||||||
}
|
|
||||||
// Socket would block, we'll try again later
|
|
||||||
return APIError::WOULD_BLOCK;
|
|
||||||
} else if (sent == 0) {
|
} else if (sent == 0) {
|
||||||
// Nothing sent but not an error
|
// Nothing sent but not an error
|
||||||
return APIError::WOULD_BLOCK;
|
return APIError::WOULD_BLOCK;
|
||||||
@@ -305,12 +306,12 @@ APIError APINoiseFrameHelper::loop() {
|
|||||||
// WOULD_BLOCK when no more data is available to read
|
// WOULD_BLOCK when no more data is available to read
|
||||||
while (state_ != State::DATA && this->socket_->ready()) {
|
while (state_ != State::DATA && this->socket_->ready()) {
|
||||||
APIError err = state_action_();
|
APIError err = state_action_();
|
||||||
if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
if (err == APIError::WOULD_BLOCK) {
|
if (err == APIError::WOULD_BLOCK) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (err != APIError::OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use base class implementation for buffer sending
|
// Use base class implementation for buffer sending
|
||||||
|
|||||||
@@ -132,6 +132,9 @@ class APIFrameHelper {
|
|||||||
|
|
||||||
// Helper method to buffer data from IOVs
|
// Helper method to buffer data from IOVs
|
||||||
void buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len);
|
void buffer_data_from_iov_(const struct iovec *iov, int iovcnt, uint16_t total_write_len);
|
||||||
|
|
||||||
|
// Common socket write error handling
|
||||||
|
APIError handle_socket_write_error_();
|
||||||
template<typename StateEnum>
|
template<typename StateEnum>
|
||||||
APIError write_raw_(const struct iovec *iov, int iovcnt, socket::Socket *socket, std::vector<uint8_t> &tx_buf,
|
APIError write_raw_(const struct iovec *iov, int iovcnt, socket::Socket *socket, std::vector<uint8_t> &tx_buf,
|
||||||
const std::string &info, StateEnum &state, StateEnum failed_state);
|
const std::string &info, StateEnum &state, StateEnum failed_state);
|
||||||
|
|||||||
Reference in New Issue
Block a user