This commit is contained in:
J. Nick Koston 2025-07-10 14:12:57 -10:00
parent 2cb0418c95
commit 949249cac3
No known key found for this signature in database
3 changed files with 40 additions and 55 deletions

View File

@ -104,18 +104,18 @@ const FieldMetaV3 DeviceInfoResponse::FIELDS_V3[20] = {
42,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(DeviceInfoResponse, area) & 0xFF),
.message_type_id =
static_cast<uint8_t>(9 | (((PROTO_FIELD_OFFSET(DeviceInfoResponse, area) >> 8) & 0x0F) << 4))}}};
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(DeviceInfoResponse, area) >> 8) & 0x03) | (9 << 2))}}};
const RepeatedFieldMetaV3 DeviceInfoResponse::REPEATED_FIELDS_V3[2] = {
{20,
42,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(DeviceInfoResponse, devices) & 0xFF),
.message_type_id =
static_cast<uint8_t>(0 | (((PROTO_FIELD_OFFSET(DeviceInfoResponse, devices) >> 8) & 0x0F) << 4))}},
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(DeviceInfoResponse, devices) >> 8) & 0x03) | (0 << 2))}},
{21,
42,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(DeviceInfoResponse, areas) & 0xFF),
.message_type_id =
static_cast<uint8_t>(1 | (((PROTO_FIELD_OFFSET(DeviceInfoResponse, areas) >> 8) & 0x0F) << 4))}}};
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(DeviceInfoResponse, areas) >> 8) & 0x03) | (1 << 2))}}};
#ifdef USE_BINARY_SENSOR
const FieldMetaV3 ListEntitiesBinarySensorResponse::FIELDS_V3[10] = {
{1, 8, {.offset = PROTO_FIELD_OFFSET(ListEntitiesBinarySensorResponse, object_id)}},
@ -352,17 +352,17 @@ const RepeatedFieldMetaV3 HomeassistantServiceResponse::REPEATED_FIELDS_V3[3] =
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data) & 0xFF),
.message_type_id =
static_cast<uint8_t>(2 | (((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data) >> 8) & 0x0F) << 4))}},
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data) >> 8) & 0x03) | (2 << 2))}},
{3,
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data_template) & 0xFF),
.message_type_id = static_cast<uint8_t>(
2 | (((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data_template) >> 8) & 0x0F) << 4))}},
((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data_template) >> 8) & 0x03) | (2 << 2))}},
{4,
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(HomeassistantServiceResponse, variables) & 0xFF),
.message_type_id = static_cast<uint8_t>(
2 | (((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, variables) >> 8) & 0x0F) << 4))}}};
((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, variables) >> 8) & 0x03) | (2 << 2))}}};
const FieldMetaV3 SubscribeHomeAssistantStateResponse::FIELDS_V3[3] = {
{1, 8, {.offset = PROTO_FIELD_OFFSET(SubscribeHomeAssistantStateResponse, entity_id)}},
{2, 8, {.offset = PROTO_FIELD_OFFSET(SubscribeHomeAssistantStateResponse, attribute)}},
@ -384,7 +384,7 @@ const RepeatedFieldMetaV3 ListEntitiesServicesResponse::REPEATED_FIELDS_V3[1] =
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(ListEntitiesServicesResponse, args) & 0xFF),
.message_type_id =
static_cast<uint8_t>(3 | (((PROTO_FIELD_OFFSET(ListEntitiesServicesResponse, args) >> 8) & 0x0F) << 4))}}};
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(ListEntitiesServicesResponse, args) >> 8) & 0x03) | (3 << 2))}}};
const FieldMetaV3 ExecuteServiceArgument::FIELDS_V3[5] = {
{1, 0, {.offset = PROTO_FIELD_OFFSET(ExecuteServiceArgument, bool_)}},
{2, 1, {.offset = PROTO_FIELD_OFFSET(ExecuteServiceArgument, legacy_int)}},
@ -403,7 +403,7 @@ const RepeatedFieldMetaV3 ExecuteServiceRequest::REPEATED_FIELDS_V3[1] = {
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(ExecuteServiceRequest, args) & 0xFF),
.message_type_id =
static_cast<uint8_t>(4 | (((PROTO_FIELD_OFFSET(ExecuteServiceRequest, args) >> 8) & 0x0F) << 4))}}};
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(ExecuteServiceRequest, args) >> 8) & 0x03) | (4 << 2))}}};
#ifdef USE_CAMERA
const FieldMetaV3 ListEntitiesCameraResponse::FIELDS_V3[8] = {
{1, 8, {.offset = PROTO_FIELD_OFFSET(ListEntitiesCameraResponse, object_id)}},
@ -628,7 +628,7 @@ const RepeatedFieldMetaV3 ListEntitiesMediaPlayerResponse::REPEATED_FIELDS_V3[1]
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(ListEntitiesMediaPlayerResponse, supported_formats) & 0xFF),
.message_type_id = static_cast<uint8_t>(
5 | (((PROTO_FIELD_OFFSET(ListEntitiesMediaPlayerResponse, supported_formats) >> 8) & 0x0F) << 4))}}};
((PROTO_FIELD_OFFSET(ListEntitiesMediaPlayerResponse, supported_formats) >> 8) & 0x03) | (5 << 2))}}};
const FieldMetaV3 MediaPlayerStateResponse::FIELDS_V3[5] = {
{1, 12, {.offset = PROTO_FIELD_OFFSET(MediaPlayerStateResponse, key)}},
{2, 7, {.offset = PROTO_FIELD_OFFSET(MediaPlayerStateResponse, state)}},
@ -665,13 +665,13 @@ const RepeatedFieldMetaV3 BluetoothLEAdvertisementResponse::REPEATED_FIELDS_V3[3
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, service_data) & 0xFF),
.message_type_id = static_cast<uint8_t>(
6 | (((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, service_data) >> 8) & 0x0F) << 4))}},
((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, service_data) >> 8) & 0x03) | (6 << 2))}},
{6,
10,
{.offset_low =
static_cast<uint8_t>(PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, manufacturer_data) & 0xFF),
.message_type_id = static_cast<uint8_t>(
6 | (((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, manufacturer_data) >> 8) & 0x0F) << 4))}}};
((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, manufacturer_data) >> 8) & 0x03) | (6 << 2))}}};
const FieldMetaV3 BluetoothLERawAdvertisement::FIELDS_V3[4] = {
{1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothLERawAdvertisement, address)}},
{2, 5, {.offset = PROTO_FIELD_OFFSET(BluetoothLERawAdvertisement, rssi)}},
@ -683,7 +683,7 @@ const RepeatedFieldMetaV3 BluetoothLERawAdvertisementsResponse::REPEATED_FIELDS_
{.offset_low =
static_cast<uint8_t>(PROTO_FIELD_OFFSET(BluetoothLERawAdvertisementsResponse, advertisements) & 0xFF),
.message_type_id = static_cast<uint8_t>(
7 | (((PROTO_FIELD_OFFSET(BluetoothLERawAdvertisementsResponse, advertisements) >> 8) & 0x0F) << 4))}}};
((PROTO_FIELD_OFFSET(BluetoothLERawAdvertisementsResponse, advertisements) >> 8) & 0x03) | (7 << 2))}}};
const FieldMetaV3 BluetoothDeviceRequest::FIELDS_V3[4] = {
{1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothDeviceRequest, address)}},
{2, 7, {.offset = PROTO_FIELD_OFFSET(BluetoothDeviceRequest, request_type)}},
@ -709,7 +709,7 @@ const RepeatedFieldMetaV3 BluetoothGATTCharacteristic::REPEATED_FIELDS_V3[2] = {
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(BluetoothGATTCharacteristic, descriptors) & 0xFF),
.message_type_id = static_cast<uint8_t>(
8 | (((PROTO_FIELD_OFFSET(BluetoothGATTCharacteristic, descriptors) >> 8) & 0x0F) << 4))}}};
((PROTO_FIELD_OFFSET(BluetoothGATTCharacteristic, descriptors) >> 8) & 0x03) | (8 << 2))}}};
const FieldMetaV3 BluetoothGATTService::FIELDS_V3[1] = {
{2, 2, {.offset = PROTO_FIELD_OFFSET(BluetoothGATTService, handle)}}};
const RepeatedFieldMetaV3 BluetoothGATTService::REPEATED_FIELDS_V3[2] = {
@ -718,7 +718,7 @@ const RepeatedFieldMetaV3 BluetoothGATTService::REPEATED_FIELDS_V3[2] = {
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(BluetoothGATTService, characteristics) & 0xFF),
.message_type_id =
static_cast<uint8_t>(9 | (((PROTO_FIELD_OFFSET(BluetoothGATTService, characteristics) >> 8) & 0x0F) << 4))}}};
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(BluetoothGATTService, characteristics) >> 8) & 0x03) | (9 << 2))}}};
const FieldMetaV3 BluetoothGATTGetServicesResponse::FIELDS_V3[1] = {
{1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, address)}}};
const RepeatedFieldMetaV3 BluetoothGATTGetServicesResponse::REPEATED_FIELDS_V3[1] = {
@ -726,7 +726,7 @@ const RepeatedFieldMetaV3 BluetoothGATTGetServicesResponse::REPEATED_FIELDS_V3[1
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, services) & 0xFF),
.message_type_id = static_cast<uint8_t>(
10 | (((PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, services) >> 8) & 0x0F) << 4))}}};
((PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, services) >> 8) & 0x03) | (10 << 2))}}};
const FieldMetaV3 BluetoothGATTGetServicesDoneResponse::FIELDS_V3[1] = {
{1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothGATTGetServicesDoneResponse, address)}}};
const FieldMetaV3 BluetoothGATTReadRequest::FIELDS_V3[2] = {
@ -805,7 +805,7 @@ const FieldMetaV3 VoiceAssistantRequest::FIELDS_V3[5] = {
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(VoiceAssistantRequest, audio_settings) & 0xFF),
.message_type_id = static_cast<uint8_t>(
105 | (((PROTO_FIELD_OFFSET(VoiceAssistantRequest, audio_settings) >> 8) & 0x0F) << 4))}},
((PROTO_FIELD_OFFSET(VoiceAssistantRequest, audio_settings) >> 8) & 0x03) | (105 << 2))}},
{5, 8, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantRequest, wake_word_phrase)}}};
const FieldMetaV3 VoiceAssistantResponse::FIELDS_V3[2] = {
{1, 2, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantResponse, port)}},
@ -820,7 +820,7 @@ const RepeatedFieldMetaV3 VoiceAssistantEventResponse::REPEATED_FIELDS_V3[1] = {
10,
{.offset_low = static_cast<uint8_t>(PROTO_FIELD_OFFSET(VoiceAssistantEventResponse, data) & 0xFF),
.message_type_id =
static_cast<uint8_t>(11 | (((PROTO_FIELD_OFFSET(VoiceAssistantEventResponse, data) >> 8) & 0x0F) << 4))}}};
static_cast<uint8_t>(((PROTO_FIELD_OFFSET(VoiceAssistantEventResponse, data) >> 8) & 0x03) | (11 << 2))}}};
const FieldMetaV3 VoiceAssistantAudio::FIELDS_V3[2] = {
{1, 9, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantAudio, data)}},
{2, 0, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantAudio, end)}}};
@ -851,7 +851,7 @@ const RepeatedFieldMetaV3 VoiceAssistantConfigurationResponse::REPEATED_FIELDS_V
{.offset_low =
static_cast<uint8_t>(PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, available_wake_words) & 0xFF),
.message_type_id = static_cast<uint8_t>(
12 | (((PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, available_wake_words) >> 8) & 0x0F) << 4))}},
((PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, available_wake_words) >> 8) & 0x03) | (12 << 2))}},
{2, 8, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, active_wake_words)}}};
const RepeatedFieldMetaV3 VoiceAssistantSetConfiguration::REPEATED_FIELDS_V3[1] = {
{1, 8, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantSetConfiguration, active_wake_words)}}};

View File

@ -77,8 +77,9 @@ constexpr uint8_t get_wire_type(ProtoFieldType type) {
// Macro to calculate field offset without triggering -Winvalid-offsetof
// This uses the same approach as offsetof but with explicit reinterpret_cast
#define PROTO_FIELD_OFFSET(Type, Member) /* NOLINT(bugprone-macro-parentheses) */ \
static_cast<uint16_t>(reinterpret_cast<size_t>(&reinterpret_cast<Type *>(16)->Member) - 16)
#define PROTO_FIELD_OFFSET(Type, Member) \
static_cast<uint16_t>(reinterpret_cast<size_t>(&reinterpret_cast<Type *>(16)->Member) - \
16) /* NOLINT(bugprone-macro-parentheses) */
/// Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit
class ProtoVarInt {
@ -288,8 +289,8 @@ struct FieldMetaV3 {
union {
uint16_t offset; // For non-message types: offset in class (0-65535)
struct {
uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset
uint8_t message_type_id; // For TYPE_MESSAGE: index into MESSAGE_HANDLERS
uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset (bits 0-7)
uint8_t message_type_id; // For TYPE_MESSAGE: bits 0-1: offset high (bits 8-9), bits 2-7: handler index (0-63)
};
};
@ -298,13 +299,13 @@ struct FieldMetaV3 {
uint8_t get_precalced_size() const { return ((type_and_size >> 5) & 0x03) + 1; }
uint16_t get_offset() const {
if (get_type() == ProtoFieldType::TYPE_MESSAGE) {
// Reconstruct full offset from packed fields
// Bits 0-7 from offset_low, bits 8-11 from upper nibble of message_type_id
return static_cast<uint16_t>(offset_low) | (static_cast<uint16_t>(message_type_id & 0xF0) << 4);
// Reconstruct full offset from packed fields (10-bit offset)
// Bits 0-7 from offset_low, bits 8-9 from lower 2 bits of message_type_id
return static_cast<uint16_t>(offset_low) | (static_cast<uint16_t>(message_type_id & 0x03) << 8);
}
return offset;
}
uint8_t get_message_type_id() const { return message_type_id & 0x0F; }
uint8_t get_message_type_id() const { return message_type_id >> 2; } // Upper 6 bits for type ID (0-63)
};
// V2 structures removed - we only use V3 now
@ -476,8 +477,8 @@ struct RepeatedFieldMetaV3 {
union {
uint16_t offset; // For non-message types: offset in class (0-65535)
struct {
uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset
uint8_t message_type_id; // For TYPE_MESSAGE: index into REPEATED_MESSAGE_HANDLERS
uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset (bits 0-7)
uint8_t message_type_id; // For TYPE_MESSAGE: bits 0-1: offset high (bits 8-9), bits 2-7: handler index (0-63)
};
};
@ -486,13 +487,13 @@ struct RepeatedFieldMetaV3 {
uint8_t get_precalced_size() const { return ((type_and_size >> 5) & 0x03) + 1; }
uint16_t get_offset() const {
if (get_type() == ProtoFieldType::TYPE_MESSAGE) {
// Reconstruct full offset from packed fields
// Bits 0-7 from offset_low, bits 8-11 from upper nibble of message_type_id
return static_cast<uint16_t>(offset_low) | (static_cast<uint16_t>(message_type_id & 0xF0) << 4);
// Reconstruct full offset from packed fields (10-bit offset)
// Bits 0-7 from offset_low, bits 8-9 from lower 2 bits of message_type_id
return static_cast<uint16_t>(offset_low) | (static_cast<uint16_t>(message_type_id & 0x03) << 8);
}
return offset;
}
uint8_t get_message_type_id() const { return message_type_id & 0x0F; }
uint8_t get_message_type_id() const { return message_type_id >> 2; } // Upper 6 bits for type ID (0-63)
};
// V2 structures removed - we only use V3 now
@ -577,35 +578,17 @@ class ProtoService {
return true;
}
};
// Type-specific functions removed - V3 inlines all operations directly
// Template enum field functions removed - V3 inlines all operations directly
// Repeated field handling functions removed - V3 inlines encoding directly
// Note: The template encode_repeated_message_field is still used by the message handler registry
template<typename MessageType>
void encode_repeated_message_field(ProtoWriteBuffer &buffer, const void *field_ptr, uint8_t field_num);
// Size calculation for repeated fields removed - V3 inlines size calculation directly
// Note: The template size_repeated_message_field is still used by the message handler registry
template<typename MessageType>
void size_repeated_message_field(uint32_t &total_size, const void *field_ptr, uint8_t precalced_field_id_size);
// Repeated field decode functions removed - V3 inlines decoding directly
// Forward declarations for message field template functions
template<typename MessageType>
void encode_message_field(ProtoWriteBuffer &buffer, const void *field_ptr, uint8_t field_num);
template<typename MessageType>
void size_message_field(uint32_t &total_size, const void *field_ptr, uint8_t precalced_field_id_size, bool force);
// Template decode functions removed - V3 inlines decoding directly
// Core shared functions removed - V2 metadata is used directly
} // namespace api
} // namespace esphome

View File

@ -1350,8 +1350,10 @@ def build_message_type(
ti._ti.type_name
)
offset = f"PROTO_FIELD_OFFSET({desc.name}, {ti.field_name})"
# Bits 0-1: bits 8-9 of offset (extends offset to 10 bits = 1023)
# Bits 2-7: actual message type ID (supports 64 types)
repeated_fields_v3.append(
f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast<uint8_t>({offset} & 0xFF), .message_type_id = static_cast<uint8_t>({message_type_id} | ((({offset} >> 8) & 0x0F) << 4))}}}}"
f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast<uint8_t>({offset} & 0xFF), .message_type_id = static_cast<uint8_t>((({offset} >> 8) & 0x03) | ({message_type_id} << 2))}}}}"
)
else:
# Non-message types use full offset
@ -1376,11 +1378,11 @@ def build_message_type(
offset = f"PROTO_FIELD_OFFSET({desc.name}, {ti.field_name})"
# Since we have so few message types, we can use the upper bits of
# message_type_id to extend the offset range
# Bits 0-3: actual message type ID (supports 16 types)
# Bits 4-7: bits 8-11 of offset (extends offset to 12 bits = 4096)
# message_type_id to store the actual type ID
# Bits 0-1: bits 8-9 of offset (extends offset to 10 bits = 1023)
# Bits 2-7: actual message type ID (supports 64 types)
regular_fields_v3.append(
f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast<uint8_t>({offset} & 0xFF), .message_type_id = static_cast<uint8_t>({message_type_id} | ((({offset} >> 8) & 0x0F) << 4))}}}}"
f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast<uint8_t>({offset} & 0xFF), .message_type_id = static_cast<uint8_t>((({offset} >> 8) & 0x03) | ({message_type_id} << 2))}}}}"
)
else:
# Non-message types use full offset