Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions include/sendspin/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ namespace sendspin {
/// @brief Configuration for a SendspinClient instance
/// Filled in by the platform (e.g., ESPHome) before calling start_server()
struct SendspinClientConfig {
std::string client_id; ///< Unique client identifier (e.g., MAC address)
std::string name; ///< Friendly display name
/// Unique client identifier. When left empty, the library falls back to the detected local
/// network interface MAC address (the same value used for device_info.mac_address).
std::string client_id;
std::string name; ///< Friendly display name

std::optional<std::string> product_name{}; ///< Device product name (optional)
std::optional<std::string> manufacturer{}; ///< Manufacturer name, e.g., "ESPHome" (optional)
Expand Down
19 changes: 14 additions & 5 deletions src/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,17 +438,26 @@ void SendspinClient::cleanup_connection_state() {

std::string SendspinClient::build_hello_message() {
ClientHelloMessage msg;
msg.client_id = this->config_.client_id;
msg.name = this->config_.name;

// Use the explicitly configured MAC when provided; otherwise fall back to platform detection
// (reliable on ESP, best-effort on host). Leaves the field absent if neither is available.
const std::optional<std::string> interface_mac =
this->config_.mac_address ? this->config_.mac_address : platform_get_interface_mac();

// Some integrations use the network MAC as the Sendspin client_id. If they leave it empty,
// default to the same active-interface MAC advertised in device_info instead of forcing them
// to duplicate platform-specific MAC detection.
msg.client_id = this->config_.client_id;
if (msg.client_id.empty() && interface_mac.has_value()) {
msg.client_id = interface_mac.value();
}

DeviceInfoObject device_info{};
device_info.product_name = this->config_.product_name;
device_info.manufacturer = this->config_.manufacturer;
device_info.software_version = this->config_.software_version;
// Use the explicitly configured MAC when provided; otherwise fall back to platform detection
// (reliable on ESP, best-effort on host). Leaves the field absent if neither is available.
device_info.mac_address =
this->config_.mac_address ? this->config_.mac_address : platform_get_interface_mac();
device_info.mac_address = interface_mac;
msg.device_info = device_info;

msg.version = 1;
Expand Down
11 changes: 11 additions & 0 deletions src/connection_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,11 @@ void ConnectionManager::on_new_connection(std::shared_ptr<SendspinServerConnecti
};

std::lock_guard<std::mutex> lock(this->conn_ptr_mutex_);
SendspinConnection* accepted_conn = nullptr;
if (this->current_connection_ == nullptr) {
SS_LOGD(TAG, "No existing connection, accepting as current");
this->current_connection_ = std::move(conn);
accepted_conn = this->current_connection_.get();
} else {
SS_LOGD(TAG, "Existing connection present, setting as pending for handoff");
if (this->pending_connection_ != nullptr) {
Expand All @@ -348,6 +350,15 @@ void ConnectionManager::on_new_connection(std::shared_ptr<SendspinServerConnecti
return;
}
this->pending_connection_ = std::move(conn);
accepted_conn = this->pending_connection_.get();
}

// Some ESP-IDF/httpd versions complete the WebSocket upgrade without dispatching the initial
// HTTP_GET request to websocket_handler(). Arm the hello retry from the accept path as well so
// server-initiated connections always receive client/hello. If the GET callback arrives later,
// initiate_hello() only re-arms the existing per-connection retry entry.
if (accepted_conn != nullptr) {
this->initiate_hello(accepted_conn);
}
}

Expand Down
Loading