mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-31 15:12:06 +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