mirror of
https://github.com/esphome/esphome.git
synced 2025-10-18 17:53:47 +01:00
Merge branch 'fixed_vector_wifi' into integration
This commit is contained in:
@@ -1519,7 +1519,7 @@ message BluetoothGATTCharacteristic {
|
|||||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
||||||
uint32 handle = 2;
|
uint32 handle = 2;
|
||||||
uint32 properties = 3;
|
uint32 properties = 3;
|
||||||
repeated BluetoothGATTDescriptor descriptors = 4 [(fixed_vector) = true];
|
repeated BluetoothGATTDescriptor descriptors = 4;
|
||||||
|
|
||||||
// New field for efficient UUID (v1.12+)
|
// New field for efficient UUID (v1.12+)
|
||||||
// Only one of uuid or short_uuid will be set.
|
// Only one of uuid or short_uuid will be set.
|
||||||
@@ -1531,7 +1531,7 @@ message BluetoothGATTCharacteristic {
|
|||||||
message BluetoothGATTService {
|
message BluetoothGATTService {
|
||||||
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
repeated uint64 uuid = 1 [(fixed_array_size) = 2, (fixed_array_skip_zero) = true];
|
||||||
uint32 handle = 2;
|
uint32 handle = 2;
|
||||||
repeated BluetoothGATTCharacteristic characteristics = 3 [(fixed_vector) = true];
|
repeated BluetoothGATTCharacteristic characteristics = 3;
|
||||||
|
|
||||||
// New field for efficient UUID (v1.12+)
|
// New field for efficient UUID (v1.12+)
|
||||||
// Only one of uuid or short_uuid will be set.
|
// Only one of uuid or short_uuid will be set.
|
||||||
|
@@ -64,10 +64,4 @@ extend google.protobuf.FieldOptions {
|
|||||||
// This is typically done through methods returning const T& or special accessor
|
// This is typically done through methods returning const T& or special accessor
|
||||||
// methods like get_options() or supported_modes_for_api_().
|
// methods like get_options() or supported_modes_for_api_().
|
||||||
optional string container_pointer = 50001;
|
optional string container_pointer = 50001;
|
||||||
|
|
||||||
// fixed_vector: Use FixedVector instead of std::vector for repeated fields
|
|
||||||
// When set, the repeated field will use FixedVector<T> which requires calling
|
|
||||||
// init(size) before adding elements. This eliminates std::vector template overhead
|
|
||||||
// and is ideal when the exact size is known before populating the array.
|
|
||||||
optional bool fixed_vector = 50013 [default=false];
|
|
||||||
}
|
}
|
||||||
|
@@ -1923,7 +1923,7 @@ class BluetoothGATTCharacteristic final : public ProtoMessage {
|
|||||||
std::array<uint64_t, 2> uuid{};
|
std::array<uint64_t, 2> uuid{};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
uint32_t properties{0};
|
uint32_t properties{0};
|
||||||
FixedVector<BluetoothGATTDescriptor> descriptors{};
|
std::vector<BluetoothGATTDescriptor> descriptors{};
|
||||||
uint32_t short_uuid{0};
|
uint32_t short_uuid{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(ProtoSize &size) const override;
|
void calculate_size(ProtoSize &size) const override;
|
||||||
@@ -1937,7 +1937,7 @@ class BluetoothGATTService final : public ProtoMessage {
|
|||||||
public:
|
public:
|
||||||
std::array<uint64_t, 2> uuid{};
|
std::array<uint64_t, 2> uuid{};
|
||||||
uint32_t handle{0};
|
uint32_t handle{0};
|
||||||
FixedVector<BluetoothGATTCharacteristic> characteristics{};
|
std::vector<BluetoothGATTCharacteristic> characteristics{};
|
||||||
uint32_t short_uuid{0};
|
uint32_t short_uuid{0};
|
||||||
void encode(ProtoWriteBuffer buffer) const override;
|
void encode(ProtoWriteBuffer buffer) const override;
|
||||||
void calculate_size(ProtoSize &size) const override;
|
void calculate_size(ProtoSize &size) const override;
|
||||||
|
@@ -749,29 +749,13 @@ class ProtoSize {
|
|||||||
template<typename MessageType>
|
template<typename MessageType>
|
||||||
inline void add_repeated_message(uint32_t field_id_size, const std::vector<MessageType> &messages) {
|
inline void add_repeated_message(uint32_t field_id_size, const std::vector<MessageType> &messages) {
|
||||||
// Skip if the vector is empty
|
// Skip if the vector is empty
|
||||||
if (!messages.empty()) {
|
if (messages.empty()) {
|
||||||
// Use the force version for all messages in the repeated field
|
return;
|
||||||
for (const auto &message : messages) {
|
|
||||||
add_message_object_force(field_id_size, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
// Use the force version for all messages in the repeated field
|
||||||
* @brief Calculates and adds the sizes of all messages in a repeated field to the total message size (FixedVector
|
for (const auto &message : messages) {
|
||||||
* version)
|
add_message_object_force(field_id_size, message);
|
||||||
*
|
|
||||||
* @tparam MessageType The type of the nested messages in the FixedVector
|
|
||||||
* @param messages FixedVector of message objects
|
|
||||||
*/
|
|
||||||
template<typename MessageType>
|
|
||||||
inline void add_repeated_message(uint32_t field_id_size, const FixedVector<MessageType> &messages) {
|
|
||||||
// Skip if the fixed vector is empty
|
|
||||||
if (!messages.empty()) {
|
|
||||||
// Use the force version for all messages in the repeated field
|
|
||||||
for (const auto &message : messages) {
|
|
||||||
add_message_object_force(field_id_size, message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -230,8 +230,8 @@ void BluetoothConnection::send_service_for_discovery_() {
|
|||||||
service_resp.handle = service_result.start_handle;
|
service_resp.handle = service_result.start_handle;
|
||||||
|
|
||||||
if (total_char_count > 0) {
|
if (total_char_count > 0) {
|
||||||
// Initialize FixedVector with exact count and process characteristics
|
// Reserve space and process characteristics
|
||||||
service_resp.characteristics.init(total_char_count);
|
service_resp.characteristics.reserve(total_char_count);
|
||||||
uint16_t char_offset = 0;
|
uint16_t char_offset = 0;
|
||||||
esp_gattc_char_elem_t char_result;
|
esp_gattc_char_elem_t char_result;
|
||||||
while (true) { // characteristics
|
while (true) { // characteristics
|
||||||
@@ -275,8 +275,8 @@ void BluetoothConnection::send_service_for_discovery_() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize FixedVector with exact count and process descriptors
|
// Reserve space and process descriptors
|
||||||
characteristic_resp.descriptors.init(total_desc_count);
|
characteristic_resp.descriptors.reserve(total_desc_count);
|
||||||
uint16_t desc_offset = 0;
|
uint16_t desc_offset = 0;
|
||||||
esp_gattc_descr_elem_t desc_result;
|
esp_gattc_descr_elem_t desc_result;
|
||||||
while (true) { // descriptors
|
while (true) { // descriptors
|
||||||
|
@@ -554,7 +554,7 @@ void WiFiComponent::start_scanning() {
|
|||||||
// Using insertion sort instead of std::stable_sort saves flash memory
|
// Using insertion sort instead of std::stable_sort saves flash memory
|
||||||
// by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
|
// by avoiding template instantiations (std::rotate, std::stable_sort, lambdas)
|
||||||
// IMPORTANT: This sort is stable (preserves relative order of equal elements)
|
// IMPORTANT: This sort is stable (preserves relative order of equal elements)
|
||||||
static void insertion_sort_scan_results(std::vector<WiFiScanResult> &results) {
|
template<typename VectorType> static void insertion_sort_scan_results(VectorType &results) {
|
||||||
const size_t size = results.size();
|
const size_t size = results.size();
|
||||||
for (size_t i = 1; i < size; i++) {
|
for (size_t i = 1; i < size; i++) {
|
||||||
// Make a copy to avoid issues with move semantics during comparison
|
// Make a copy to avoid issues with move semantics during comparison
|
||||||
|
@@ -121,6 +121,14 @@ struct EAPAuth {
|
|||||||
|
|
||||||
using bssid_t = std::array<uint8_t, 6>;
|
using bssid_t = std::array<uint8_t, 6>;
|
||||||
|
|
||||||
|
// Use std::vector for RP2040 since scan count is unknown (callback-based)
|
||||||
|
// Use FixedVector for other platforms where count is queried first
|
||||||
|
#ifdef USE_RP2040
|
||||||
|
template<typename T> using wifi_scan_vector_t = std::vector<T>;
|
||||||
|
#else
|
||||||
|
template<typename T> using wifi_scan_vector_t = FixedVector<T>;
|
||||||
|
#endif
|
||||||
|
|
||||||
class WiFiAP {
|
class WiFiAP {
|
||||||
public:
|
public:
|
||||||
void set_ssid(const std::string &ssid);
|
void set_ssid(const std::string &ssid);
|
||||||
@@ -278,7 +286,7 @@ class WiFiComponent : public Component {
|
|||||||
std::string get_use_address() const;
|
std::string get_use_address() const;
|
||||||
void set_use_address(const std::string &use_address);
|
void set_use_address(const std::string &use_address);
|
||||||
|
|
||||||
const std::vector<WiFiScanResult> &get_scan_result() const { return scan_result_; }
|
const wifi_scan_vector_t<WiFiScanResult> &get_scan_result() const { return scan_result_; }
|
||||||
|
|
||||||
network::IPAddress wifi_soft_ap_ip();
|
network::IPAddress wifi_soft_ap_ip();
|
||||||
|
|
||||||
@@ -386,7 +394,7 @@ class WiFiComponent : public Component {
|
|||||||
std::string use_address_;
|
std::string use_address_;
|
||||||
std::vector<WiFiAP> sta_;
|
std::vector<WiFiAP> sta_;
|
||||||
std::vector<WiFiSTAPriority> sta_priorities_;
|
std::vector<WiFiSTAPriority> sta_priorities_;
|
||||||
std::vector<WiFiScanResult> scan_result_;
|
wifi_scan_vector_t<WiFiScanResult> scan_result_;
|
||||||
WiFiAP selected_ap_;
|
WiFiAP selected_ap_;
|
||||||
WiFiAP ap_;
|
WiFiAP ap_;
|
||||||
optional<float> output_power_;
|
optional<float> output_power_;
|
||||||
|
@@ -696,7 +696,15 @@ void WiFiComponent::wifi_scan_done_callback_(void *arg, STATUS status) {
|
|||||||
this->retry_connect();
|
this->retry_connect();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count the number of results first
|
||||||
auto *head = reinterpret_cast<bss_info *>(arg);
|
auto *head = reinterpret_cast<bss_info *>(arg);
|
||||||
|
size_t count = 0;
|
||||||
|
for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) {
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->scan_result_.init(count);
|
||||||
for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) {
|
for (bss_info *it = head; it != nullptr; it = STAILQ_NEXT(it, next)) {
|
||||||
WiFiScanResult res({it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]},
|
WiFiScanResult res({it->bssid[0], it->bssid[1], it->bssid[2], it->bssid[3], it->bssid[4], it->bssid[5]},
|
||||||
std::string(reinterpret_cast<char *>(it->ssid), it->ssid_len), it->channel, it->rssi,
|
std::string(reinterpret_cast<char *>(it->ssid), it->ssid_len), it->channel, it->rssi,
|
||||||
|
@@ -784,7 +784,7 @@ void WiFiComponent::wifi_process_event_(IDFWiFiEvent *data) {
|
|||||||
}
|
}
|
||||||
records.resize(number);
|
records.resize(number);
|
||||||
|
|
||||||
scan_result_.reserve(number);
|
scan_result_.init(number);
|
||||||
for (int i = 0; i < number; i++) {
|
for (int i = 0; i < number; i++) {
|
||||||
auto &record = records[i];
|
auto &record = records[i];
|
||||||
bssid_t bssid;
|
bssid_t bssid;
|
||||||
|
@@ -411,7 +411,7 @@ void WiFiComponent::wifi_scan_done_callback_() {
|
|||||||
if (num < 0)
|
if (num < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this->scan_result_.reserve(static_cast<unsigned int>(num));
|
this->scan_result_.init(static_cast<unsigned int>(num));
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
String ssid = WiFi.SSID(i);
|
String ssid = WiFi.SSID(i);
|
||||||
wifi_auth_mode_t authmode = WiFi.encryptionType(i);
|
wifi_auth_mode_t authmode = WiFi.encryptionType(i);
|
||||||
|
@@ -1415,8 +1415,6 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
# Check if this is a pointer field by looking for container_pointer option
|
# Check if this is a pointer field by looking for container_pointer option
|
||||||
self._container_type = get_field_opt(field, pb.container_pointer, "")
|
self._container_type = get_field_opt(field, pb.container_pointer, "")
|
||||||
self._use_pointer = bool(self._container_type)
|
self._use_pointer = bool(self._container_type)
|
||||||
# Check if this should use FixedVector instead of std::vector
|
|
||||||
self._use_fixed_vector = get_field_opt(field, pb.fixed_vector, False)
|
|
||||||
|
|
||||||
# For repeated fields, we need to get the base type info
|
# For repeated fields, we need to get the base type info
|
||||||
# but we can't call create_field_type_info as it would cause recursion
|
# but we can't call create_field_type_info as it would cause recursion
|
||||||
@@ -1440,8 +1438,6 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
if "<" in self._container_type and ">" in self._container_type:
|
if "<" in self._container_type and ">" in self._container_type:
|
||||||
return f"const {self._container_type}*"
|
return f"const {self._container_type}*"
|
||||||
return f"const {self._container_type}<{self._ti.cpp_type}>*"
|
return f"const {self._container_type}<{self._ti.cpp_type}>*"
|
||||||
if self._use_fixed_vector:
|
|
||||||
return f"FixedVector<{self._ti.cpp_type}>"
|
|
||||||
return f"std::vector<{self._ti.cpp_type}>"
|
return f"std::vector<{self._ti.cpp_type}>"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Reference in New Issue
Block a user